package mh.map;

import java.util.ArrayList;

import mh.entity.object.EntityObject;

/**
 * The layer that contains each of the entity of objects player in this specific map.
 * 
 * @author Gianmarco Laggia
 * 
 */
public class ObjectsLayer extends Layer {

	/**
	 * The list of all the entities in this layer
	 */
	private ArrayList<EntityObject>	objects;				// TODO
	private EntityObject[][]		objectsMatrix;			// TODO the new way to check if a tile is avaible should count on the object stack.
	private boolean					foreground	= false;

	/**
	 * 
	 * @param x
	 *            The initial x position of the sprite when created the map
	 * @param y
	 *            The initial y position of the sprite when created the map
	 * @param width
	 *            The width of the layer
	 * @param height
	 *            The height of the layer
	 */
	public ObjectsLayer(double x, double y, int width, int height) {
		super(x, y, width, height);
		this.objects = new ArrayList<EntityObject>();
		this.objectsMatrix = new EntityObject[width][height];
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see mh.Layer#draw(double)
	 */
	@Override
	public void draw(long delta) {
		if (this.foreground) {
			for (int i = 0; i < this.objects.size(); i++) {
				EntityObject obj = this.objects.get(i);
				obj.setPlayerCoord(this.actualx, this.actualy);
				obj.draw(delta, this.foreground);
			}
		} else {
			for (int i = 0; i < this.objects.size(); i++) {
				EntityObject obj = this.objects.get(i);
				obj.setPlayerCoord(this.actualx, this.actualy);
				obj.draw(delta, this.foreground);
			}
			this.lastFrameChange += delta;
			if (this.lastFrameChange > this.frameDuration) {
				this.lastFrameChange = 0;
				if (this.actualx < this.finalx) {
					this.actualx += 0.5;
				} else if (this.actualx > this.finalx) {
					this.actualx -= 0.5;
				} else if (this.actualy < this.finaly) {
					this.actualy += 0.5;
				} else if (this.actualy > this.finaly) {
					this.actualy -= 0.5;
				}
			}
		}
		this.foreground = !this.foreground;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see mh.Layer#isAvaible(int, int)
	 */
	@Override
	public boolean isAvaible(int x, int y) {
		for (int i = 0; i < this.objects.size(); i++) {
			EntityObject object = this.objects.get(i);
			if ((Math.ceil(object.getX()) == x) && (Math.ceil(object.getY()) == y)) {
				if (!object.isWalkable()) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Sets the object at the specified position. Does nothing if (tx, ty) falls outside of this layer.
	 * 
	 * @param x
	 *            x position of the object
	 * @param y
	 *            y position of the object
	 * @param eo
	 *            the object to place
	 */
	public void setObjectAt(int x, int y, EntityObject eo) {
		if (this.bounds.contains(x, y) && (eo != null)) {
			eo.teleportTo(x, y);
			this.objects.add(eo);
		}
	}

	/**
	 * Returns a list of all the Entities that are in this map.
	 * 
	 * @return A list of objects.
	 */
	public ArrayList<EntityObject> getObjects() {
		return this.objects;
	}

	@Override
	public String toString() {
		return this.objects.toString();
	}
}
